////////////////////////////////////////////////////////////////////////////
//
//  Crytek Engine Source File.
//  Copyright (C), Crytek Studios, 2002.
// -------------------------------------------------------------------------
//  File name:   LoaderDBA.h
//  Version:     v1.00
//  Created:     31/08/2006 by Alexey Medvedev.
//  Compilers:   Visual Studio.NET
//  Description: 
// -------------------------------------------------------------------------
//  History:
//
////////////////////////////////////////////////////////////////////////////

#ifndef __DBALoader_h__
#define __DBALoader_h__
#pragma once

#include "ControllerOpt.h"


struct CInternalDatabaseInfo
{
	DynArray<IKeyTimesInformation*> m_arrKeyTimesArray;
	DynArray<ITrackRotationStorage*> m_arrRotationTracksArray;
	DynArray<ITrackPositionStorage*> m_arrPositionTracksArray;

	DynArray<_smart_ptr<IKeyTimesInformation> > m_arrKeyTimes;
	DynArray<ITrackRotationStorage*> m_arrRotationTracks;
	DynArray<ITrackPositionStorage*> m_arrPositionTracks;
	int m_iTotalControllers;

	DynArray<char> m_Storage;
	CControllerOptNonVirtual * m_pControllersInplace;

	CInternalDatabaseInfo()
	{
		m_pControllersInplace = NULL;
	};

	~CInternalDatabaseInfo()
	{
		if (m_pControllersInplace)
		{
			delete [] m_pControllersInplace;
			m_pControllersInplace = 0;
		}
		Clear();
	}

	void Clear()
	{


		for (std::size_t i =0, end =m_arrRotationTracksArray.size(); i < end; ++i )
		{
			if (m_arrRotationTracksArray[i])
				ControllerHelper::DeleteRotationControllerPtrArray(m_arrRotationTracksArray[i]);
		}

		for (std::size_t i =0, end =m_arrKeyTimesArray.size(); i < end; ++i )
		{
			if (m_arrKeyTimesArray[i])
				ControllerHelper::DeleteTimesControllerPtrArray(m_arrKeyTimesArray[i]);
		}
		for (std::size_t i =0, end =m_arrPositionTracksArray.size(); i < end; ++i )
		{

			if (m_arrPositionTracksArray[i])
				ControllerHelper::DeletePositionControllerPtrArray(m_arrPositionTracksArray[i]);
		}

	}

	void GetMemoryUsage( ICrySizer *pSizer ) const
	{
		pSizer->AddObject(m_arrKeyTimesArray);
		pSizer->AddObject(m_arrRotationTracksArray);
		pSizer->AddObject(m_arrPositionTracksArray);
		pSizer->AddObject(m_arrKeyTimes);
		pSizer->AddObject(m_arrRotationTracks);
		pSizer->AddObject(m_arrPositionTracks);		
		pSizer->AddObject(m_Storage);
		pSizer->AddObject(m_pControllersInplace, sizeof(CControllerOptNonVirtual)*m_iTotalControllers);
	}
};


struct CGlobalHeaderDBA : public IStreamCallback
{
	friend class CAnimationManager;


	CGlobalHeaderDBA();

	~CGlobalHeaderDBA()
	{
		if (m_pDatabaseInfo)
			delete m_pDatabaseInfo;
	}

	void GetMemoryUsage( ICrySizer *pSizer ) const;
	const char *GetLastError() const { return m_LastError; }

	bool LoadChunks(IChunkFile* pChunkFile);

	bool ReadControllers(IChunkFile::ChunkDesc* pChunkDesc);
	bool ReadController905 (IChunkFile::ChunkDesc* pChunkDesc);
	int32 FindFormat(uint32 num, std::vector<uint32>& vec)
	{
		for (size_t i =0; i < vec.size(); ++i)
		{
			if ( num < vec[i+1])
				return (int)i;
		}
		return -1;
	}

	void CreateDatabaseDBA( const char* filename );
	void LoadDatabaseDBA( const char *sForCharacter );
	bool StartStreamingDBA( bool highPriority );

	void StreamAsyncOnComplete(IReadStream* pStream, unsigned nError);
	void StreamOnComplete (IReadStream* pStream, unsigned nError);
	void DeleteDatabaseDBA( );
	const size_t SizeOf_DBA() const;
	bool InMemory();
	void ReportLoadError( const char *sForCharacter,const char *sReason );

	CInternalDatabaseInfo* m_pDatabaseInfoStreaming;
	CInternalDatabaseInfo* m_pDatabaseInfo;
	string m_strFilePathDBA;
	uint32 m_FilePathDBACRC32;
	uint16 m_nUsedAnimations;
	uint16 m_nEmpty;
	uint8 m_nTCount;
	uint8  m_IsRequested;
	uint8  m_bLoadFailed;
	uint8  m_bDBALock;
	string m_LastError;
	volatile uint8 m_bIsDeleting;
};


#endif
